package edu.csumb.itcd.teammario;
import java.awt.Color;
import java.awt.Font;
import java.awt.Event;
import java.awt.MouseInfo;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Transparency;
import java.awt.geom.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.sql.SQLException;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Game extends JPanel implements Runnable, ActionListener,  KeyListener, MouseListener, MouseWheelListener{
    
    /**
     * @param args
     */
    public static int gameCount = 0;
    private Thread gameThread;
    private Player player = new Player();
    private BulletList bullets;
    private EnemyList enemies;
    private TowerList towers;
    private Collision collision;
    private Color enemyc;
    boolean mousePressed = false;
    private int direction = 3; // 1 = up, 2 = left, 3 = down,  4 = right
    private LeaderBoard lb;

    
    /**
     * This paints the top bar that contains stats and info (non-interactive)
     */
    public void paintComponent(Graphics g){
        
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        
        //Draw Tower Bullets
        synchronized (BulletList.getTowerBulletArray())
        {
            for (Bullet bullet : BulletList.getTowerBulletArray())
            {
            	g2.setColor(Color.blue);
               bullet.paintBullet(g2);
            }
        }
        //Draw Towers
        synchronized (TowerList.getTowerArray())
        {
            for (Tower tower : TowerList.getTowerArray())
            {
                tower.paintTower(g);
            }
        }
        //Draw Player Bullets
        g2.setColor(Color.BLUE);
        synchronized (BulletList.getPlayerBulletArray())
        {
            for (Bullet bullet : BulletList.getPlayerBulletArray())
            {            	
                bullet.paintBullet(g2);
            }
        }
        //Draw Enemy Bullets
        
        synchronized (BulletList.getEnemyBulletArray())
        {
            for (Bullet bullet : BulletList.getEnemyBulletArray())
            {
                bullet.paintBullet(g2);
            }
        }

        // Draw Player
        g.setColor(Color.yellow);
        if (Player.getPoisonReceived().isCurrentlyPoisoned() == true)
        {
        	g.setColor(Color.GREEN);
        }
        else
        {
        	g.setColor(Color.yellow);
        }
        g.fillRect(Player.getPlayerPosition().x, Player.getPlayerPosition().y, Player.getWidth(), Player.getHeight());
        g.setColor(Color.black);
        g.drawRect(Player.getPlayerPosition().x, Player.getPlayerPosition().y, Player.getWidth(), Player.getHeight());
        
        //Draw Enemy
        synchronized (EnemyList.enemyArray)
        {
            for (Enemy enemy : enemies.getEnemyArray())
            {
                enemy.paintEnemy(g2);
            }
        }
        
        synchronized (EnemyList.getMoneyArray())
        {
        	for (Money money : EnemyList.getMoneyArray())
        	{
        		money.paintMoney(g);
        	}
        }
        //Stat Box
        g.setFont(this.getFont());
        g.setColor(Color.white);
        g.fillRect(-1, -1, 800, 55);
        g.setColor(Color.black);
        g.drawRect(-1, -1, 800, 55);
        // Draw Health Bar
        g.setColor(Color.black);
        g.drawString("Hp: " + Player.getCurrentHealth() + "/" + player.getMaxHealth(), 700, 15);
        g.drawString("Kill Count: " + LeaderBoard.getKillCount(), 45, 15);
        g.drawString("Level: " + EnemyFactory.getCurrentLevel(), 150, 15);
        g.drawString("Towers Available: " + TowerList.getMaxTowerCount(), 225, 15);
        g.drawString("Money: " + Player.getMoney(), 350, 15);
		g.drawString("Current Weapon: " + Player.getCurrentWeapon().getWeaponName(), 45, 35);
        g.drawRect(700, 18, 65, 10);
        g.setColor(Color.green);
        g.fillRect(701, 19, (Player.getCurrentHealth() * 64)/ player.getMaxHealth(), 9);
    }
    
    /**
     * Game constructor
     */
    public Game(){
        
    	bullets = new BulletList();
        enemies = new EnemyList();
        towers = new TowerList();
        collision= new Collision();
//        lb = new LeaderBoard();
        
        gameThread= new Thread(this);
        gameThread.start();
        
        addKeyListener(this);
        addMouseListener(this);
        addMouseWheelListener(this);
        this.setBounds(-1, -1, 800, 600);
        player.setGheight(this.getHeight()-70);
        player.setGwidth(this.getWidth());
        setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
    }
    
    /**n  
     * This is where the game will actually run
     */
    public void run() {
        while(true){
            if (Setup.isPaused() == false && Setup.isLevelEnded() == false && Setup.isGameOver() == false)
            {
	            player.movePlayer();
	           	Player.setCurrentHealth(Player.getPoisonReceived().poisonTarget(Player.getCurrentHealth()));
	            enemies.updatePlayerPosition(Player.getPlayerPosition());
//	            bullets.run();
//	            enemies.run();
//	            towers.run();
//	            collision.run();
	            gameCount ++;
	            
	            if (Player.getCurrentHealth() == 0)
	            {
	            	towers.reset();
	            	Setup.setGameOver(true);
	            }
	            if (mousePressed == true && this.getMousePosition() != null && this.getMousePosition().y > 55)
	            {
	                
	                Player.getWeaponByIndex(Player.getCurrentWeaponIndex()).playerFire(Player.getPlayerPosition(), new Point(this.getMousePosition().x, this.getMousePosition().y));
	            }
	            if(this.getMousePosition() != null && this.getMousePosition().y < 55)
	            {
	                setCursor(new Cursor(Cursor.HAND_CURSOR));
	            }
	            else
	            {
	                setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
	            }
            } else
            {
            	player.setPlayerDown(false);
            	player.setPlayerUp(false);
            	player.setPlayerLeft(false);
            	player.setPlayerRight(false);
            }
            
            repaint();
            
            
            try
            {
                Thread.sleep(30);
            }
            catch(InterruptedException ex)
            {
                
            }
            
            this.requestFocus();
        }
        
    }
    
    public void reset()
    {
    	player.reset();
    	enemies.reset();
    	towers.reset();
    	bullets.reset();
    	EnemyFactory.start();
    }
    
    public void restartLevel()
    {
    	player.reset();
    	enemies.reset();
    	EnemyFactory.restartLevel();
    }
    
    @Override
    public void mouseClicked(MouseEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void mousePressed(MouseEvent arg0) {
        // TODO Auto-generated method stub
        //System.out.println(player.getPlayerPosition());
//        System.out.println("Click: " + arg0.getPoint());
        mousePressed = true;
        if (SwingUtilities.isMiddleMouseButton(arg0))
        {
        	Player.changeWeapon();
        }
    }
    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub
        mousePressed = false;
        
    }
    
    public void mouseWheelMoved(MouseWheelEvent arg0)
    {
//    	int rotation;
//    	int currentWeapon = 0;
//    	rotation = arg0.getWheelRotation();
//    	
    	Player.changeWeapon();
    }
    
    @Override
    public void keyPressed(KeyEvent evt) {
         switch(evt.getKeyCode()){
        // Player movement
            case KeyEvent.VK_W:
                player.setPlayerUp(true);
                break;
            case KeyEvent.VK_S:
                player.setPlayerDown(true);
                break;
            case KeyEvent.VK_A:
                player.setPlayerLeft(true);
                break;
            case KeyEvent.VK_D:
                player.setPlayerRight(true);
                    break;
            case KeyEvent.VK_1:
                towers.spawnTower(new Tower(new Point(Player.getPlayerPosition().x - Player.getWidth()/2, Player.getPlayerPosition().y - Player.getHeight()/2), new Weapon(Tower.getDamage(), Tower.getRateOfFire())));
                break;
                case KeyEvent.VK_2:
                towers.spawnTower(new PoisonTower(new Point(Player.getPlayerPosition().x - Player.getWidth()/2, Player.getPlayerPosition().y - Player.getHeight()/2), new PoisonWeapon(PoisonTower.getDamage(), PoisonTower.getRateOfFire(), PoisonTower.getDuration())));
                break;
            case KeyEvent.VK_3:
                towers.spawnTower(new ShotgunTower(new Point(Player.getPlayerPosition().x - Player.getWidth()/2, Player.getPlayerPosition().y - Player.getHeight()/2), new ShotGunWeapon(ShotgunTower.getDamage(), ShotgunTower.getRateOfFire())));
                break;
         }    
    }
    @Override
    public void keyReleased(KeyEvent evt) {
         switch(evt.getKeyCode()){
            // Player movement
            case KeyEvent.VK_W:
                player.setPlayerUp(false);
                break;
            case KeyEvent.VK_S:
                player.setPlayerDown(false);
                break;
            case KeyEvent.VK_A:
                player.setPlayerLeft(false);
                break;
            case KeyEvent.VK_D:
                player.setPlayerRight(false);
                break;
            case KeyEvent.VK_ESCAPE:
            	if (Setup.isPaused())
            	{
            		Setup.setPause(false);
            	} else
            	{
            		Setup.setPause(true);
            		
            	}
            	break;

             }    
        
    }
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        
    }
}

